from flask import Blueprint, request, jsonify
from models import db
from models.users import Resource, Role, Permission, AdminUser
from sqlalchemy.exc import IntegrityError
from sqlalchemy import text

# 创建蓝图
menu_bp = Blueprint('menu_api', __name__)

# ==================== 菜单管理 ====================

@menu_bp.route('/menus', methods=['GET'])
def get_menus():
    """获取所有菜单"""
    try:
        # 使用原生SQL查询
        result = db.session.execute(text("""
            SELECT id, name, pid, level, topid, url, icon, sort, status, created_at 
            FROM resources 
            WHERE status = 1 
            ORDER BY sort, id
        """)).fetchall()
        
        menu_list = []
        for row in result:
            menu_list.append({
                'id': row[0],
                'name': row[1],
                'path': row[5],  # url字段作为path
                'component': row[1],  # name作为component
                'icon': row[6],
                'pid': row[2],
                'level': row[3],
                'topid': row[4],
                'sort': row[7],
                'status': bool(row[8]),
                'created_at': row[9].strftime('%Y-%m-%d %H:%M:%S') if row[9] else None
            })
        
        return jsonify({'code': 200, 'message': '获取成功', 'data': menu_list})
    except Exception as e:
        return jsonify({'code': 500, 'message': f'获取失败: {str(e)}'}), 500

@menu_bp.route('/menus', methods=['POST'])
def create_menu():
    """创建菜单"""
    try:
        data = request.get_json()
        name = data.get('name')
        path = data.get('path')
        component = data.get('component')
        icon = data.get('icon')
        pid = data.get('pid', 0)
        level = data.get('level', 1)
        topid = data.get('topid', 0)
        sort = data.get('sort', 0)
        status = data.get('status', True)
        description = data.get('description', '')
        
        if not name:
            return jsonify({'code': 400, 'message': '菜单名称不能为空'}), 400
        
        # 创建菜单
        menu = Resource(
            name=name,
            url=path,
            icon=icon,
            pid=pid,
            level=level,
            topid=topid,
            sort=sort,
            status=status
        )
        db.session.add(menu)
        db.session.commit()
        
        return jsonify({
            'code': 200,
            'message': '创建成功',
            'data': {
                'id': menu.id,
                'name': menu.name,
                'path': menu.url,
                'component': component,
                'icon': menu.icon,
                'pid': menu.pid,
                'level': menu.level,
                'topid': menu.topid,
                'sort': menu.sort,
                'status': menu.status
            }
        })
    except Exception as e:
        db.session.rollback()
        return jsonify({'code': 500, 'message': f'创建失败: {str(e)}'}), 500

@menu_bp.route('/menus/<int:menu_id>', methods=['GET'])
def get_menu(menu_id):
    """获取单个菜单"""
    try:
        # 使用原生SQL查询
        result = db.session.execute(text("""
            SELECT id, name, pid, level, topid, url, icon, sort, status, created_at 
            FROM resources 
            WHERE id = :menu_id
        """), {'menu_id': menu_id}).fetchone()
        
        if not result:
            return jsonify({'code': 404, 'message': '菜单不存在'}), 404
        
        return jsonify({
            'code': 200,
            'message': '获取成功',
            'data': {
                'id': result[0],
                'name': result[1],
                'path': result[5],  # url字段作为path
                'component': result[1],  # name作为component
                'icon': result[6],
                'pid': result[2],
                'level': result[3],
                'topid': result[4],
                'sort': result[7],
                'status': bool(result[8]),
                'created_at': result[9].strftime('%Y-%m-%d %H:%M:%S') if result[9] else None
            }
        })
    except Exception as e:
        return jsonify({'code': 500, 'message': f'获取失败: {str(e)}'}), 500

@menu_bp.route('/menus/<int:menu_id>', methods=['PUT'])
def update_menu(menu_id):
    """更新菜单"""
    try:
        # 检查菜单是否存在
        result = db.session.execute(text("SELECT id FROM resources WHERE id = :menu_id"), {'menu_id': menu_id}).fetchone()
        if not result:
            return jsonify({'code': 404, 'message': '菜单不存在'}), 404
        
        data = request.get_json()
        
        # 构建更新SQL
        update_fields = []
        params = {'menu_id': menu_id}
        
        if 'name' in data:
            update_fields.append("name = :name")
            params['name'] = data['name']
        if 'path' in data:
            update_fields.append("url = :url")
            params['url'] = data['path']
        if 'icon' in data:
            update_fields.append("icon = :icon")
            params['icon'] = data['icon']
        if 'pid' in data:
            update_fields.append("pid = :pid")
            params['pid'] = data['pid']
        if 'level' in data:
            update_fields.append("level = :level")
            params['level'] = data['level']
        if 'topid' in data:
            update_fields.append("topid = :topid")
            params['topid'] = data['topid']
        if 'sort' in data:
            update_fields.append("sort = :sort")
            params['sort'] = data['sort']
        if 'status' in data:
            update_fields.append("status = :status")
            params['status'] = data['status']
        
        if update_fields:
            sql = f"UPDATE resources SET {', '.join(update_fields)} WHERE id = :menu_id"
            db.session.execute(text(sql), params)
            db.session.commit()
        
        return jsonify({'code': 200, 'message': '更新成功'})
    except Exception as e:
        db.session.rollback()
        return jsonify({'code': 500, 'message': f'更新失败: {str(e)}'}), 500

@menu_bp.route('/menus/<int:menu_id>', methods=['DELETE'])
def delete_menu(menu_id):
    """删除菜单"""
    try:
        # 使用原生SQL查询检查菜单是否存在
        result = db.session.execute(text("SELECT id FROM resources WHERE id = :menu_id"), {'menu_id': menu_id}).fetchone()
        if not result:
            return jsonify({'code': 404, 'message': '菜单不存在'}), 404
        
        # 检查是否有子菜单
        child_result = db.session.execute(text("SELECT id FROM resources WHERE pid = :menu_id"), {'menu_id': menu_id}).fetchone()
        if child_result:
            return jsonify({'code': 400, 'message': '该菜单下有子菜单，无法删除'}), 400
        
        # 删除相关的权限记录（按外键依赖顺序删除）
        # 1. 先删除角色权限关联
        db.session.execute(text("DELETE FROM role_permissions WHERE permission_id IN (SELECT id FROM permissions WHERE resource_id = :menu_id)"), {'menu_id': menu_id})
        # 2. 再删除用户资源关联
        db.session.execute(text("DELETE FROM user_resources WHERE resource_id = :menu_id"), {'menu_id': menu_id})
        # 3. 最后删除权限记录
        db.session.execute(text("DELETE FROM permissions WHERE resource_id = :menu_id"), {'menu_id': menu_id})
        
        # 删除菜单
        db.session.execute(text("DELETE FROM resources WHERE id = :menu_id"), {'menu_id': menu_id})
        db.session.commit()
        
        return jsonify({'code': 200, 'message': '删除成功'})
    except Exception as e:
        db.session.rollback()
        return jsonify({'code': 500, 'message': f'删除失败: {str(e)}'}), 500

# ==================== 用户权限管理 ====================

@menu_bp.route('/users/<int:user_id>/resources', methods=['GET'])
def get_user_resources(user_id):
    """获取用户资源权限"""
    try:
        user = AdminUser.query.get(user_id)
        if not user:
            return jsonify({'code': 404, 'message': '用户不存在'}), 404
        
        resources = user.resources.all()
        result = []
        for resource in resources:
            result.append({
                'id': resource.id,
                'name': resource.name,
                'path': resource.url,
                'icon': resource.icon,
                'level': resource.level,
                'pid': resource.pid
            })
        
        return jsonify({'code': 200, 'message': '获取成功', 'data': result})
    except Exception as e:
        return jsonify({'code': 500, 'message': f'获取失败: {str(e)}'}), 500

@menu_bp.route('/users/<int:user_id>/resources', methods=['POST'])
def assign_user_resources(user_id):
    """为用户分配资源权限"""
    try:
        user = AdminUser.query.get(user_id)
        if not user:
            return jsonify({'code': 404, 'message': '用户不存在'}), 404
        
        data = request.get_json()
        resource_ids = data.get('resource_ids', [])
        
        # 清除现有资源
        user.resources.clear()
        
        # 添加新资源
        for resource_id in resource_ids:
            resource = Resource.query.get(resource_id)
            if resource:
                user.resources.append(resource)
        
        db.session.commit()
        
        return jsonify({'code': 200, 'message': '分配成功'})
    except Exception as e:
        db.session.rollback()
        return jsonify({'code': 500, 'message': f'分配失败: {str(e)}'}), 500

@menu_bp.route('/roles/<int:role_id>/permissions', methods=['GET'])
def get_role_permissions(role_id):
    """获取角色权限"""
    try:
        role = Role.query.get(role_id)
        if not role:
            return jsonify({'code': 404, 'message': '角色不存在'}), 404
        
        permissions = role.permissions.all()
        result = []
        for permission in permissions:
            result.append({
                'id': permission.id,
                'name': permission.name,
                'action': permission.action,
                'resource_id': permission.resource_id
            })
        
        return jsonify({'code': 200, 'message': '获取成功', 'data': result})
    except Exception as e:
        return jsonify({'code': 500, 'message': f'获取失败: {str(e)}'}), 500

@menu_bp.route('/roles/<int:role_id>/permissions', methods=['POST'])
def assign_role_permissions(role_id):
    """为角色分配权限"""
    try:
        role = Role.query.get(role_id)
        if not role:
            return jsonify({'code': 404, 'message': '角色不存在'}), 404
        
        data = request.get_json()
        permission_ids = data.get('permission_ids', [])
        
        # 清除现有权限
        role.permissions.clear()
        
        # 添加新权限
        for permission_id in permission_ids:
            permission = Permission.query.get(permission_id)
            if permission:
                role.permissions.append(permission)
        
        db.session.commit()
        
        return jsonify({'code': 200, 'message': '分配成功'})
    except Exception as e:
        db.session.rollback()
        return jsonify({'code': 500, 'message': f'分配失败: {str(e)}'}), 500
